%options template=LexerTemplateF.gi

%options filter=snooperKWLexer.gi

%Globals
    /.

    ./
%End

%Define

    $kw_lexer_class /.%snooperKWLexer./

%End

%Include
   LexerBasicMapF.gi
%End

%Export
    --
    MACRO_IDENTIFIER
    DollarSign
    NUMBER
    CRLF

    HEX_MACRO_PREFIX
    

    IDENTIFIER
    
    STRING_LITERAL

    PLUS_PLUS
    MINUS_MINUS
    EQUAL_EQUAL
    LESS_EQUAL
    GREATER_EQUAL
    NOT_EQUAL
    LEFT_SHIFT
    RIGHT_SHIFT
    UNSIGNED_RIGHT_SHIFT
    PLUS_EQUAL
    MINUS_EQUAL
    MULTIPLY_EQUAL
    DIVIDE_EQUAL
    AND_EQUAL
    OR_EQUAL
    XOR_EQUAL
    REMAINDER_EQUAL
    LEFT_SHIFT_EQUAL
    RIGHT_SHIFT_EQUAL
    UNSIGNED_RIGHT_SHIFT_EQUAL
    OR_OR
    AND_AND
    PLUS
    MINUS
    NOT
    REMAINDER
    XOR
    AND
    MULTIPLY
    OR
    TWIDDLE
    DIVIDE
    GREATER
    LESS
    LPAREN
    RPAREN
    LBRACE
    RBRACE
    LBRACKET
    RBRACKET
    SEMICOLON
    QUESTION
    AT
    COLON
    COMMA
    DOT
    EQUAL
    ELLIPSIS
   
        
%End

%Terminals
    CtlCharNotWS

    LF   CR   HT   FF

    a    b    c    d    e    f    g    h    i    j    k    l    m
    n    o    p    q    r    s    t    u    v    w    x    y    z
    _ 

    A    B    C    D    E    F    G    H    I    J    K    L    M
    N    O    P    Q    R    S    T    U    V    W    X    Y    Z

    0    1    2    3    4    5    6    7    8    9

    AfterASCII   ::= '\u0080..\ufffe'
    Space        ::= ' '
    LF           ::= NewLine
    CR           ::= Return
    HT           ::= HorizontalTab
    FF           ::= FormFeed
    DoubleQuote  ::= '"'
    SingleQuote  ::= "'"
    Percent      ::= '%'
    VerticalBar  ::= '|'
    Exclamation  ::= '!'
    AtSign       ::= '@'
    BackQuote    ::= '`'
    Tilde        ::= '~'
    Sharp        ::= '#'
    DollarSign   ::= '$'
    Ampersand    ::= '&'
    Caret        ::= '^'
    Colon        ::= ':'
    SemiColon    ::= ';'
    BackSlash    ::= '\'
    LeftBrace    ::= '{'
    RightBrace   ::= '}'
    LeftBracket  ::= '['
    RightBracket ::= ']'
    QuestionMark     ::= '?'
    Comma        ::= ','
    Dot          ::= '.'
    LessThan     ::= '<'
    GreaterThan  ::= '>'
    Plus         ::= '+'
    Minus        ::= '-'
    Slash        ::= '/'
    Star         ::= '*'
    LeftParen    ::= '('
    RightParen   ::= ')'
    Equal        ::= '='
%End

%Start
    Token
%End

%Rules

    Token ::= Identifier   /.%BeginAction    checkForKeyWord(); %EndAction./

    Token ::= MacroIdentifier  /.%BeginAction    makeToken(%_MACRO_IDENTIFIER); %EndAction./

    Token ::= '"' SLBody '"'
                /.%BeginAction
                    makeToken(%_STRING_LITERAL);
                %EndAction./



    Token ::= White         /.%BeginAction    skipToken(); %EndAction./

    Token ::= SLC           /.%BeginAction     skipToken();; %EndAction./

    Token ::= Eol            /.%BeginAction   makeToken(%_CRLF); %EndAction./
            
    Token ::= '+'
        /.%BeginAction
                    makeToken(%_PLUS);
          %EndAction
        ./
    Token ::= '-'
        /.%BeginAction
                    makeToken(%_MINUS);
          %EndAction
        ./

    Token ::= '*'
        /.%BeginAction
                    makeToken(%_MULTIPLY);
          %EndAction
        ./

    Token ::= '/'
        /.%BeginAction
                    makeToken(%_DIVIDE);
          %EndAction
        ./

    Token ::= '('
        /.%BeginAction
                    makeToken(%_LPAREN);
          %EndAction
        ./

    Token ::= ')'
        /.%BeginAction
                    makeToken(%_RPAREN);
          %EndAction
        ./

    Token ::= '='
        /.%BeginAction
                    makeToken(%_EQUAL);
          %EndAction
        ./

    Token ::= ','
        /.%BeginAction
                    makeToken(%_COMMA);
          %EndAction
        ./

    Token ::= ':'
        /.%BeginAction
                    makeToken(%_COLON);
          %EndAction
        ./

    Token ::= ';'
        /.%BeginAction
                    makeToken(%_SEMICOLON);
          %EndAction
        ./

    Token ::= '^'
        /.%BeginAction
                    makeToken(%_XOR);
          %EndAction
        ./

    Token ::= '%'
        /.%BeginAction
                    makeToken(%_REMAINDER);
          %EndAction
        ./

    Token ::= '~'
        /.%BeginAction
                    makeToken(%_TWIDDLE);
          %EndAction
        ./

    Token ::= '|'
        /.%BeginAction
                    makeToken(%_OR);
          %EndAction
        ./

    Token ::= '&'
        /.%BeginAction
                    makeToken(%_AND);
          %EndAction
        ./

    Token ::= '<'
        /.%BeginAction
                    makeToken(%_LESS);
          %EndAction
        ./

    Token ::= '>'
        /.%BeginAction
                    makeToken(%_GREATER);
          %EndAction
        ./

    Token ::= '.'
        /.%BeginAction
                    makeToken(%_DOT);
          %EndAction
        ./

    Token ::= '!'
        /.%BeginAction
                    makeToken(%_NOT);
          %EndAction
        ./

    Token ::= '['
        /.%BeginAction
                    makeToken(%_LBRACKET);
          %EndAction
        ./

    Token ::= ']'
        /.%BeginAction
                    makeToken(%_RBRACKET);
          %EndAction
        ./

    Token ::= '{'
        /.%BeginAction
                    makeToken(%_LBRACE);
          %EndAction
        ./

    Token ::= '}'
        /.%BeginAction
                    makeToken(%_RBRACE);
          %EndAction
        ./

    Token ::= '?'
        /.%BeginAction
                    makeToken(%_QUESTION);
          %EndAction
        ./

    Token ::= '@'
        /.%BeginAction
                    makeToken(%_AT);
          %EndAction
        ./

    Token ::= '+' '+'
        /.%BeginAction
                    makeToken(%_PLUS_PLUS);
          %EndAction
        ./

    Token ::= '-' '-'
        /.%BeginAction
                    makeToken(%_MINUS_MINUS);
          %EndAction
        ./

    Token ::= '=' '='
        /.%BeginAction
                    makeToken(%_EQUAL_EQUAL);
          %EndAction
        ./

    Token ::= '<' '='
        /.%BeginAction
                    makeToken(%_LESS_EQUAL);
          %EndAction
        ./

    Token ::= '!' '='
        /.%BeginAction
                    makeToken(%_NOT_EQUAL);
          %EndAction
        ./

    Token ::= '<' '<'
        /.%BeginAction
                    makeToken(%_LEFT_SHIFT);
          %EndAction
        ./

    Token ::= '+' '='
        /.%BeginAction
                    makeToken(%_PLUS_EQUAL);
          %EndAction
        ./

    Token ::= '-' '='
        /.%BeginAction
                    makeToken(%_MINUS_EQUAL);
          %EndAction
        ./

    Token ::= '*' '='
        /.%BeginAction
                    makeToken(%_MULTIPLY_EQUAL);
          %EndAction
        ./

    Token ::= '/' '='
        /.%BeginAction
                    makeToken(%_DIVIDE_EQUAL);
          %EndAction
        ./

    Token ::= '&' '='
        /.%BeginAction
                    makeToken(%_AND_EQUAL);
          %EndAction
        ./

    Token ::= '|' '='
        /.%BeginAction
                    makeToken(%_OR_EQUAL);
          %EndAction
        ./

    Token ::= '^' '='
        /.%BeginAction
                    makeToken(%_XOR_EQUAL);
          %EndAction
        ./

    Token ::= '%' '='
        /.%BeginAction
                    makeToken(%_REMAINDER_EQUAL);
          %EndAction
        ./

    Token ::= '<' '<' '='
        /.%BeginAction
                    makeToken(%_LEFT_SHIFT_EQUAL);
          %EndAction
        ./

    Token ::= '|' '|'
        /.%BeginAction
                    makeToken(%_OR_OR);
          %EndAction
        ./

    Token ::= '&' '&'
        /.%BeginAction
                    makeToken(%_AND_AND);
          %EndAction
        ./

    Token ::= '.' '.' '.'
        /.%BeginAction
                    makeToken(%_ELLIPSIS);
          %EndAction
        ./
    Token ::= '$' 
        /.%BeginAction
                    makeToken(%_DollarSign);
          %EndAction
        ./


    Token ::= HexMacroPrefix
    /.%BeginAction
                makeToken(%_HEX_MACRO_PREFIX);
        %EndAction
    ./   

    HexMacroPrefix ::= 0 LetterXx 

    Identifier -> Letter
                | Identifier Letter

    MacroIdentifier ::= DollarSign Identifier



    
    White ::= WhiteChar
            | White WhiteChar

    SLC ::= '/' '/'
          | SLC NotEol

    Digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

    LowerCaseLetter -> a | b | c | d | e | f | g | h | i | j | k | l | m |
                       n | o | p | q | r | s | t | u | v | w | x | y | z

    UpperCaseLetter -> A | B | C | D | E | F | G | H | I | J | K | L | M |
                       N | O | P | Q | R | S | T | U | V | W | X | Y | Z

    Letter -> LowerCaseLetter
            | UpperCaseLetter
            | _
            | Digit
            | AfterASCII

    NotDQ -> Letter
           | Digit
           | SpecialNotDQ
           | Space
           | HT
           | FF
           | EscapeSequence
           | '\' Letter

    SLBody -> %empty
            | SLBody NotDQ

    SpecialNotDQ -> '+' | '-' | '/' | '(' | ')' | '*' | '!' | '@' | '`' | '~' |
                    '%' | '&' | '^' | ':' | ';' | "'" | '|' | '{' | '}' |
                    '[' | ']' | '?' | ',' | '.' | '<' | '>' | '=' | '#'

    EscapeSequence -> '\' b
                    | '\' t
                    | '\' n
                    | '\' f
                    | '\' r
                    | '\' '"'
                    | '\' "'"
                    | '\' '\'

    
    WhiteChar ::= Space  | HT | FF

    LetterXx -> X
              | x

    SpecialNotStar ::= '+' | '-' | '(' | ')' | '"' | '!' | '@' | '`' | '~' | '.' |
                       '%' | '&' | '^' | ':' | ';' | "'" | '\' | '|' | '{' | '}' |
                       '[' | ']' | '?' | ',' | '<' | '>' | '=' | '#' | '*' | '_' |
                       '/' | '$'

    NotEol ::= Letter | Digit | SpecialNotStar | Space | HT | FF | CtlCharNotWS | '*'

    EolOption -> LF | CR
    Eol ::= EolOption | Eol EolOption
%End
